package com.ossjk.oa.system.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ossjk.core.base.controller.BaseController;
import com.ossjk.core.util.CommonUtil;
import com.ossjk.core.util.Constant;
import com.ossjk.core.util.CryptoUtils;
import com.ossjk.core.vo.ResponseBean;
import com.ossjk.core.vo.ZtreeBean;
import com.ossjk.oa.advisory.entity.School;
import com.ossjk.oa.advisory.service.IChannelService;
import com.ossjk.oa.advisory.service.ICustomerService;
import com.ossjk.oa.advisory.service.IDisciplineService;
import com.ossjk.oa.advisory.service.ISchoolService;
import com.ossjk.oa.config.wxlogin.WxLoginConfig;
import com.ossjk.oa.config.wxlogin.WxLoginVo;
import com.ossjk.oa.system.entity.Department;
import com.ossjk.oa.system.entity.Dictionary;
import com.ossjk.oa.system.entity.Employee;
import com.ossjk.oa.system.entity.EmployeePost;
import com.ossjk.oa.system.entity.Permission;
import com.ossjk.oa.system.entity.Post;
import com.ossjk.oa.system.entity.Token;
import com.ossjk.oa.system.service.IAreaService;
import com.ossjk.oa.system.service.IDepartmentService;
import com.ossjk.oa.system.service.IDictionaryService;
import com.ossjk.oa.system.service.IEmployeePostService;
import com.ossjk.oa.system.service.IEmployeeService;
import com.ossjk.oa.system.service.IPermissionService;
import com.ossjk.oa.system.service.IPostService;
import com.ossjk.oa.system.service.ITokenService;

/**
 * 主页控制器
 */
@Controller
@RequestMapping("/")
public class IndexController extends BaseController {

	@Autowired
	private IEmployeeService iEmployeeService;
	@Autowired
	private ITokenService iTokenService;
	@Autowired
	private IPermissionService iPermissionService;
	@Autowired
	private IAreaService iAreaService;
	@Autowired
	private IDepartmentService iDepartmentService;
	@Autowired
	private IDictionaryService iDictionaryService;
	@Autowired
	private ISchoolService iSchoolService;
	@Autowired
	private IDisciplineService iDisciplineService;
	@Autowired
	private IChannelService iChannelService;
	@Autowired
	private IEmployeePostService iEmployeePostService;
	@Autowired
	private IPostService iPostService;
	@Autowired
	private ICustomerService iCustomerService;

	@Autowired
	private WxLoginConfig wxLoginConfig;

	@RequestMapping("/")
	public String toIndex() {
		return "/page/index.html";
	}

	@RequestMapping("/toLogin")
	public String toLogin() {
		return "/page/login.html";
	}

	@RequestMapping("/toNoLogin")
	@ResponseBody
	public Object toNoLogin() {
		return new ResponseBean(Constant.RESPONSE_CODE_NOLOGIN, Constant.RESPONSE_MSG_NOLOGIN, null);
	}

	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	public Object login(String name, String pwd, HttpServletRequest request) {
		// 分配token
		Wrapper wrapper = Condition.create().eq("name", name);
		Employee employee = iEmployeeService.selectOne(wrapper);
		if (!CommonUtil.isBlank(employee)
				&& CommonUtil.isEquals(employee.getPwd(), CryptoUtils.encodeMD5(new String(pwd)))) {
			Token token = new Token();
			token.setUid(employee.getId());
			String tokenStr = jwtTokenUtil.generalToken(employee.getId(), employee.getName());
			token.setDuration(jwtTokenUtil.getTokenTimeOut(tokenStr));
			token.setToken(tokenStr);
			List<String> codes = iPermissionService.selectCodeByEid(employee.getId());
			Map expression = new HashMap();
			expression.put("perssion", codes);
			// 岗位id
			Wrapper wrapper2 = Condition.create().eq("eid", employee.getId());
			EmployeePost employeePost = iEmployeePostService.selectOne(wrapper2);
			expression.put(Constant.REQUEST_PID_KEY, employeePost.getPid());
			// 部门id
			Post post = iPostService.selectById(employeePost.getPid());
			expression.put(Constant.REQUEST_DID_KEY, post.getDid());
			Wrapper wrapper3 = Condition.create();
			List<Department> departments = iDepartmentService.selectList(wrapper3);
			// List dsub = new ArrayList();
			// dsub.add(post.getDid());
			List dsub = iDepartmentService.selectSubIdByPid(post.getDid());
			dsub.add(post.getDid());
			expression.put(Constant.REQUEST_DSUB_KEY, dsub);
			Wrapper wrapper4 = Condition.create();
			List<Post> posts = iPostService.selectList(wrapper4);
			// List psub = new ArrayList();
			// psub.add(employeePost.getPid());
			List psub = iPostService.selectSubIdByPid(post.getId());
			psub.add(post.getId());
			expression.put(Constant.REQUEST_PSUB_KEY, psub);
			token.setExpression(JSON.toJSONString(expression));
			iTokenService.insertNewToken(token);
			return responseSuccess(Constant.RESPONSE_MSG_SUCCESS, tokenStr);
		} else {
			return responseFail("登录失败");
		}
	}

	@RequestMapping(value = "/wxlogin")
	public String wxlogin(String code, ModelMap map, HttpSession session) throws Exception {
		System.out.println("跳转ok，code=" + code);
		WxLoginVo wxLoginVo = wxLoginConfig.wxLogin(code);
		Wrapper wrapper = Condition.create().eq("wxuid", wxLoginVo.getUnionid());
		Employee employee = iEmployeeService.selectOne(wrapper);

		if (!CommonUtil.isBlank(employee)) {
			Token token = new Token();
			token.setUid(employee.getId());
			String tokenStr = jwtTokenUtil.generalToken(employee.getId(), employee.getName());
			token.setDuration(jwtTokenUtil.getTokenTimeOut(tokenStr));
			token.setToken(tokenStr);
			List<String> codes = iPermissionService.selectCodeByEid(employee.getId());
			Map expression = new HashMap();
			expression.put("perssion", codes);
			// 岗位id
			Wrapper wrapper2 = Condition.create().eq("eid", employee.getId());
			EmployeePost employeePost = iEmployeePostService.selectOne(wrapper2);
			expression.put(Constant.REQUEST_PID_KEY, employeePost.getPid());
			// 部门id
			Post post = iPostService.selectById(employeePost.getPid());
			expression.put(Constant.REQUEST_DID_KEY, post.getDid());
			Wrapper wrapper3 = Condition.create();
			List<Department> departments = iDepartmentService.selectList(wrapper3);
			// List dsub = new ArrayList();
			// dsub.add(post.getDid());
			List dsub = iDepartmentService.selectSubIdByPid(post.getDid());
			dsub.add(post.getDid());
			expression.put(Constant.REQUEST_DSUB_KEY, dsub);
			Wrapper wrapper4 = Condition.create();
			List<Post> posts = iPostService.selectList(wrapper4);
			// List psub = new ArrayList();
			// psub.add(employeePost.getPid());
			List psub = iPostService.selectSubIdByPid(post.getId());
			psub.add(post.getId());
			expression.put(Constant.REQUEST_PSUB_KEY, psub);
			token.setExpression(JSON.toJSONString(expression));
			iTokenService.insertNewToken(token);
			return "redirect:/page/wxLogin.html?token=" + tokenStr;
		} else {
			// 为保证安全暂用session把微信暂存
			session.setAttribute("wxLoginVo", wxLoginVo);
			return "redirect:/page/bind.html?unionid=" + wxLoginVo.getUnionid();
		}

	}

	/**
	 * 绑定账号
	 * 
	 * @return
	 */
	@RequestMapping(value = "/bind", method = RequestMethod.POST)
	@ResponseBody
	public Object bind(String name, String pwd, String unionid, ModelMap map, HttpSession session) {
		Wrapper wrapper = Condition.create().eq("name", name).or().eq("mobile", name).andNew().eq("pwd",
				CryptoUtils.encodeMD5(pwd));
		Employee employee = iEmployeeService.selectOne(wrapper);
		if (!CommonUtil.isBlank(employee)) {
			session.removeAttribute("wxLoginVo");
			employee.setWxuid(unionid);
			iEmployeeService.updateById(employee);
			return responseSuccess();
		} else {
			return responseFail();
		}
	}

	@RequestMapping(value = "/getInfo", method = RequestMethod.GET)
	@ResponseBody
	public Object getInfo(HttpServletRequest request) {
		// 查询用户信息
		String uid = getCurrnetUserId();
		Employee employee = iEmployeeService.selectById(uid);
		// 查询权限
		List<Permission> permissions = iPermissionService.selectByEid(employee.getId());
		Map data = new HashMap();
		data.put("user", employee);
		data.put("permission", permissions);
		data.put("permission", permissions);
		data.put("did", request.getAttribute(Constant.REQUEST_DID_KEY));
		data.put("pid", request.getAttribute(Constant.REQUEST_PID_KEY));
		data.put("dsub", request.getAttribute(Constant.REQUEST_DSUB_KEY));
		data.put("psub", request.getAttribute(Constant.REQUEST_PSUB_KEY));
		return responseSuccess(data);
	}

	@RequestMapping(value = "/logout")
	@ResponseBody
	public Object logout() {
		String userid = getCurrnetUserId();
		Wrapper wrapper = Condition.create().eq("uid", userid);
		iTokenService.delete(wrapper);
		return responseSuccess();
	}

	@RequestMapping(value = "/getArea")
	@ResponseBody
	public Object getArea() {
		return responseSuccess(iAreaService.getArea());
	}

	@RequestMapping(value = "/getDepartment")
	@ResponseBody
	public Object getDepartment(String did) {
		List<ZtreeBean> ztreeBeans = new ArrayList();
		List<Department> departments = new ArrayList();
		if (CommonUtil.isBlank(did)) {
			Wrapper wrapper = Condition.create().orderBy("level", true).orderBy("sort", true);
			departments = iDepartmentService.selectList(wrapper);
		} else {
			List<Department> dsub = iDepartmentService.selectSubByPid(did);
			if (!CommonUtil.isBlank(dsub)) {
				departments = dsub;
				dsub = null;
			}
			departments.add(iDepartmentService.selectById(did));
		}
		// 转换ztreeBean
		if (!CommonUtil.isBlank(departments)) {
			for (Department department : departments) {
				ZtreeBean ztreeBean = new ZtreeBean();
				ztreeBean.setId(department.getId());
				ztreeBean.setPId(department.getPid());
				ztreeBean.setName(department.getName());
				ztreeBean.setOpen(true);
				ztreeBeans.add(ztreeBean);
			}
			departments = null;
		}
		return responseSuccess(ztreeBeans);

	}

	@RequestMapping(value = "/getEmployee")
	@ResponseBody
	public Object getEmployee(String did) {
		Wrapper wrapper = Condition.create().isWhere(true).ne("e.isdelete", "2").orderBy("e.crtm", true);
		if (!CommonUtil.isBlank(did)) {
			wrapper.eq("d.id", did);
		}
		Page page = iEmployeeService.selectVoPage(new Page<>(0, Integer.MAX_VALUE), wrapper);
		return responseSuccess(page.getRecords());
	}

	@RequestMapping(value = "/getAttribute")
	@ResponseBody
	public Object getAttribute() {
		Map attributeMap = (Map) getRequest().getServletContext().getAttribute(Constant.APPLICATION_ATTRIBUTE_KEY);
		if (attributeMap == null) {
			Wrapper wrapper = Condition.create().like("type", "1").orderBy("crtm", false);
			List<Dictionary> dictionaries = iDictionaryService.selectList(wrapper);
			if (!CommonUtil.isBlank(dictionaries)) {
				attributeMap = new HashMap();
				for (Dictionary dictionary : dictionaries) {
					attributeMap.put(dictionary.getDkey(), dictionary.getDvalue());
				}
				getRequest().getServletContext().setAttribute(Constant.APPLICATION_ATTRIBUTE_KEY, attributeMap);
			}

		}
		return responseSuccess(Constant.RESPONSE_MSG_SUCCESS, JSON.toJSONString(attributeMap));
	}

	@RequestMapping(value = "/updatePwd")
	@ResponseBody
	public Object updatePwd(String pwd) {
		Employee employee = new Employee();
		employee.setId(getCurrnetUserId());
		employee.setPwd(CryptoUtils.encodeMD5(pwd));
		if (iEmployeeService.updateById(employee)) {
			return responseSuccess("修改密码成功。");
		} else {
			return responseFail();
		}
	}

	@RequestMapping(value = "/getSchool")
	@ResponseBody
	public Object getSchool() {
		Wrapper wrapper = Condition.create().isWhere(true).ne("s.isdelete", "2").orderBy("crtm", false);
		return responseSuccess(iSchoolService.selectVoPage(new Page<>(0, Integer.MAX_VALUE), wrapper).getRecords());
	}

	@RequestMapping(value = "/getDiscipline/{id}")
	@ResponseBody
	public Object getDiscipline(@PathVariable("id") String id) {
		School school = iSchoolService.selectById(id);
		List list = null;
		if (!CommonUtil.isBlank(school)) {
			Wrapper wrapper = Condition.create().eq("sid", school.getId());
			list = iDisciplineService.selectList(wrapper);
		}
		return responseSuccess(list);
	}

	@RequestMapping(value = "/getChannel")
	@ResponseBody
	public Object getChannel() {
		Wrapper wrapper = Condition.create().ne("isdelete", "2").orderBy("slno", true);
		return responseSuccess(iChannelService.selectList(wrapper));
	}

	/**
	 * 所有子集部门id
	 * 
	 * @param id
	 * @param list
	 * @param list2
	 */
	private void dsubset(String id, List<Department> list, List list2) {
		for (Department object : list) {
			if (id.equals(object.getPid())) {
				list2.add(object.getId());
				dsubset(object.getId(), list, list2);
			}
		}
	}

	/**
	 * 所有子集岗位id
	 * 
	 * @param id
	 * @param list
	 * @param list2
	 */
	private void psubset(String id, List<Post> list, List list2) {
		for (Post object : list) {
			if (id.equals(object.getPid())) {
				list2.add(object.getId());
				psubset(object.getId(), list, list2);
			}
		}
	}

	@RequestMapping(value = "/getFollowCount", method = RequestMethod.GET)
	@ResponseBody
	public Object getFollowCount(HttpServletRequest request) {
		// 查询用户信息
		String uid = getCurrnetUserId();
		Wrapper wrapper = Condition.create().eq("eid", uid).ne("isdelete", 2).andNew().like("ivtm", CommonUtil.date())
				.or().like("nftm", CommonUtil.date());
		int count = iCustomerService.selectCount(wrapper);
		return responseSuccess(count);
	}

}
